package com.wlwx.simulator.codec;

import com.wlwx.simulator.message.basic.BaseInBoundMessage;
import com.wlwx.simulator.message.basic.BaseOutBoundMessage;
import com.wlwx.simulator.message.inbound.*;

import java.nio.ByteBuffer;

public class CMPPCommand {

    public static final int CMPP_LOGIN_REQ_COMMAND    = 0x00000001;
    public static final int CMPP_LOGIN_RESP_COMMAND   = 0x80000001;

    public static final int CMPP_LOGOUT_REQ_COMMAND   = 0x00000002;
    public static final int CMPP_LOGOUT_RESP_COMMAND  = 0x00000002;

    public static final int CMPP_SUBMIT_REQ_COMMAND   = 0x00000004;
    public static final int CMPP_SUBMIT_RESP_COMMAND  = 0x80000004;

    public static final int CMPP_DELIVER_REQ_COMMAND  = 0x00000005;
    public static final int CMPP_DELIVER_RESP_COMMAND = 0x80000005;

    public static final int CMPP_HEART_REQ_COMMAND    = 0x00000008;
    public static final int CMPP_HEART_RESP_COMMAND   = 0x80000008;

    private int command;
    private int sequence;
    private byte[] body;

    protected CMPPCommand() {

    }

    public static BaseInBoundMessage decode(ByteBuffer byteBuffer) {
        int len = byteBuffer.limit();
        int commandId = byteBuffer.getInt();
        int sequenceId = byteBuffer.getInt();
        byteBuffer.mark();
        // command_id 4 字节 sequence_id 4字节
        int bodyLen = len - 4 - 4;
        return headerDecode(commandId, sequenceId, byteBuffer);
    }

    private static BaseInBoundMessage headerDecode(int commandId, int sequenceId, ByteBuffer byteBuffer) {
        BaseInBoundMessage base = null;
        switch (commandId) {
            case CMPP_LOGIN_REQ_COMMAND:
                base = new LoginInBoundRequest();
                base.decode(byteBuffer);
                System.out.println(base);
                break;

            case CMPP_LOGOUT_REQ_COMMAND:
                base = new LogoutInBoundRequest();
                base.decode(byteBuffer);
                System.out.println(base);
                break;

            case CMPP_SUBMIT_REQ_COMMAND:
                base = new SubmitInBoundRequest();
                base.decode(byteBuffer);
                System.out.println(base);
                break;

            case CMPP_DELIVER_RESP_COMMAND:
                base = new DeliverInBoundResponse();
                base.decode(byteBuffer);
                System.out.println(base);
                break;
            case CMPP_HEART_REQ_COMMAND:
                base = new HearthInBoundRequest();
                base.decode(byteBuffer);
                break;
            default:
                break;
        }


        if(base != null) {
            base.setSequenceId(sequenceId);
            base.setCode(commandId);
            return base;
        }

        return null;
    }

    public static CMPPCommand createCommand(BaseOutBoundMessage message) {
        CMPPCommand command = new CMPPCommand();
        command.command  = message.getCode();
        command.sequence = message.getSequenceId();
        command.body     = message.getBody();
        return command;
    }

    public ByteBuffer encodeHeader(int bodysize) {
        int len = 4 + 4 + 4;
        ByteBuffer byteBuffer = ByteBuffer.allocate(len);

        byteBuffer.putInt(len + bodysize);
        byteBuffer.putInt(command);
        byteBuffer.putInt(sequence);

        byteBuffer.flip();
        return byteBuffer;
    }

    public byte[] encodeBody() {
        return body;
    }
}
